package com.sencorsta.ids.core.tcp.http;

import com.sencorsta.ids.core.configure.SysConfig;
import com.sencorsta.ids.core.log.Out;

import com.sencorsta.utils.string.StringUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.ThreadPerTaskExecutor;


/**
　　* @description: Http服务器
　　* @author TAO
　　* @date 2019/6/12 17:12
　　*/
public class HttpServer {

	private HttpServerHandler httpServerHandler;


	public HttpServer(){
		this.httpServerHandler = new HttpServerHandler();
	}

	private EventLoopGroup bossGroup = new NioEventLoopGroup(0,new ThreadPerTaskExecutor(new DefaultThreadFactory("Http"+"Boss")));
	private EventLoopGroup workerGroup = new NioEventLoopGroup(0,new ThreadPerTaskExecutor(new DefaultThreadFactory("Http"+"Boss")));

	public void run(String host,String realHost,int port) throws Exception {
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch) throws Exception {
							ch.pipeline().addLast("http-decoder", new TsetHttpRequestDecoder());
							ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());
							ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(1024*1024*1024));
							ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
							ch.pipeline().addLast(httpServerHandler);
						}
					});
			ChannelFuture f = b.bind(host,port).sync();
			if (StringUtil.isEmpty(realHost)){
				Out.info("Http服务绑定于 -> /" + host+":"+port);
			}else {
				realHost+=":"+port;
				Out.info("Http服务绑定于 -> /" + host+":"+port +" (公开地址:"+realHost+")");
			}
			f.channel().closeFuture().sync();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

	public void addHandler(HttpHandler handler){
		httpServerHandler.addHandler(handler);
	}

	public void echo() {
		httpServerHandler.echo();
	}

}
